﻿/*****************************************介绍*****************************************
 * 作者：Ywh
 * 创建时间：2024-05-22 15:54:43
 * 功能：更新UI脚本内容
 *      1、当前界面的通知名称类内容
 *      2、当前界面的View类内容
**************************************************************************************/

using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;

namespace Game.Framework
{
    public class UpdateUIScriptsEditor
    {
        [MenuItem("GameObject/更新UI脚本", false, 0)]
        private static void UpdateUIScripts()
        {
            var view = Selection.activeGameObject.GetComponent<BasePanel>();
            if (view != null)
            {
                string viewTypeName = view.GetType().Name;
                if (!viewTypeName.Substring(0, viewTypeName.Length - 4).Equals(view.name))
                {
                    LogManager.LogError($"UI名称与View脚本不匹配，uiName:{view.name} scriptName:{viewTypeName}", "UpdateUIScript");
                    return;
                }
                new UpdateScript(view.GetType().Namespace, $"{Selection.activeGameObject.name}Notifications");
            }
            else
            {
                var ctrl = Selection.activeGameObject.GetComponent<UIController>();
                if (ctrl == null)
                {
                    LogManager.LogError($"没有找到组件：UIController，uiName:{Selection.activeGameObject}", "UpdateUIScript");
                    return;
                }
                new UpdateScript(ctrl.GetType().Namespace, Selection.activeGameObject.name);
            }
            AssetDatabase.Refresh();
        }

        [MenuItem("GameObject/更新UI脚本", true)]
        private static bool ValidateUpdateNotification()
        {
            GameObject selectedObj = Selection.activeGameObject;
            return selectedObj != null && selectedObj.GetComponent<UIController>() != null;
        }

        // 更新通知类
        class UpdateScript
        {
            protected string m_TypeFullName, m_ScriptName;
            protected string m_Space;
            protected const string UI_DIR = "Assets/Scripts/UI/";
            protected Dictionary<string, string> m_ContainFieldDict;

            public UpdateScript(string typeFullName, string scriptName, string space = "\t\t")
            {
                m_ContainFieldDict = new Dictionary<string, string>();
                m_ScriptName = scriptName;
                m_Space = space;
                m_TypeFullName = typeFullName;
                //string[] fullNames = typeFullName.Split('.');
                //m_TypeFullName = fullNames[0];
                //for (int i = 1; i < fullNames.Length - 1; i++)
                //{
                //    m_TypeFullName += $".{fullNames[i]}";
                //    if (i == fullNames.Length - 2)
                //        m_TypeFullName += $".{m_ScriptName}";
                //}
                Update();
                m_ContainFieldDict.Clear();
            }

            private void Update()
            {
                string[] guids = AssetDatabase.FindAssets($"{m_ScriptName} t:script", new[] { UI_DIR });

                if (guids.Length > 0)
                {
                    string scriptPath = "";
                    foreach (var item in guids)
                    {
                        var pathTemp = AssetDatabase.GUIDToAssetPath(item);
                        MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(pathTemp);
                        var type = script.GetClass();
                        if (type != null && script.GetClass().Namespace == m_TypeFullName)
                        {
                            scriptPath = pathTemp;
                            break;
                        }
                    }

                    if (string.IsNullOrWhiteSpace(scriptPath) || !File.Exists(scriptPath))
                    {
                        LogManager.LogError($"脚本不存在，scriptName:{m_ScriptName}.cs scriptPath:{scriptPath}", "UpdateUIScript");
                        return;
                    }

                    string[] lines = File.ReadAllLines(scriptPath);
                    //LogManager.Log($"scriptName:{m_ScriptName} path:{scriptPath}", "UpdateUIScript");
                    int startIndex = -1;
                    int endIndex = -1;
                    for (int i = 0; i < lines.Length; i++)
                    {
                        if (lines[i].Contains("#region"))
                            startIndex = i;
                        else if (lines[i].Contains("#endregion") && startIndex != -1)
                        {
                            endIndex = i;
                            break;
                        }
                    }

                    StringBuilder content = new StringBuilder();
                    if (startIndex != -1 && endIndex != -1)
                    {
                        for (int i = 0; i < lines.Length; i++)
                        {
                            if (i <= startIndex)
                                content.AppendLine(lines[i]);
                        }

                        // 插入新内容
                        FreachTransform(Selection.activeGameObject.transform, content, Selection.activeGameObject.name);

                        for (int i = 0; i < lines.Length; i++)
                        {
                            if (i >= endIndex)
                            {
                                if (i == lines.Length - 1)
                                    content.Append(lines[i]);
                                else
                                    content.AppendLine(lines[i]);
                            }
                        }
                        File.WriteAllText(scriptPath, content.ToString());
                    }
                    else
                        LogManager.LogError($"缺少标记对：#region,#endregion，scriptName:{m_ScriptName}", "UpdateUIScript");
                }
                else
                    LogManager.LogError($"脚本不存在，rootDir:{UI_DIR} scriptName:{m_ScriptName}.cs", "UpdateUIScript");
            }

            protected virtual void FreachTransform(Transform transform, StringBuilder content, string nodePath)
            {
                foreach (Transform item in transform)
                {
                    string path = $"{nodePath}/{item.name}";
                    bool isBreak = item.name.StartsWith(UIController.BREAK_HEAD);
                    ConstructionNewContent(content, item, path);
                    if (isBreak) continue;
                    FreachTransform(item, content, path);
                }
            }

            protected virtual void ConstructionNewContent(StringBuilder content, Transform trans, string path)
            {
                bool isBreak = trans.name.StartsWith(UIController.BREAK_HEAD);
                bool isCtrl = trans.name.EndsWith(UIController.CTRL_END);
                bool isRect = trans.name.EndsWith(UIController.RECT_END);
                if (isCtrl || isRect)
                {
                    string filedContent = trans.name.Substring(0, trans.name.Length - 6);
                    if (isBreak) filedContent = filedContent.Substring(UIController.BREAK_HEAD.Length);
                    filedContent = filedContent.Replace(" ", "");
                    string fieldName = $"{filedContent}{(isRect ? "_RECT" : "_CTRL")}";
                    if (!m_ContainFieldDict.TryAdd(fieldName, filedContent))
                    {
                        LogManager.LogError($"忽略该节点，请考虑重新命名，UiElement:{path}", "UpdateUIScript", "重复字段");
                        return;
                    }
                    content.AppendLine($"{m_Space}public const string {fieldName} = \"{filedContent}\";");
                }
            }
        }
    }
}